package com.welike.shibo.controller.api;

import com.google.gson.JsonObject;
import com.welike.shibo.controller.BaseController;
import com.welike.shibo.eneity.*;
import com.welike.shibo.enums.ResultEnum;
import com.welike.shibo.service.*;
import com.welike.shibo.utils.ResultUtils;
import com.welike.shibo.utils.Tools;
import com.welike.shibo.vo.page.CommentPageVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * @author fangyu
 * @version v1.0.0
 * @since 2019-08-21 03:14
 */

@Slf4j
@Api(value = "评论相关接口")
@RestController
@RequestMapping("/api/comment")
public class ApiCommentController extends BaseController {

    @Autowired
    private ZanService zanService;

    @Autowired
    private UserService userService;

    @Autowired
    private VideoService videoService;

    @Autowired
    private MsgService msgService;

    @Autowired
    private CommentsService commentsService;

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "vid", value = "视频id", required = true),
            @ApiImplicitParam(paramType = "query", name = "content", value = "评论内容", required = true),
            @ApiImplicitParam(paramType = "query", name = "at_uid", value = "被@用户id, 没有@则为空不传", required = false)})
    @ApiOperation(value = "用户评论", notes = "用户发布评论, ")
    @PostMapping("/publish")
    public JsonResult publish(
            @RequestParam(value = "vid") String vid,
            @RequestParam(value = "content") String content,
            @RequestParam(value = "at_uid") String at_uid
    ) {
        map.clear();
        map.put("path", "/api/comment/publish");
        LoginUser loginUser = (LoginUser) getUser4Session();
        Comments comments = new Comments();
        CommentPageVo commentPageVo = new CommentPageVo();
        if (loginUser == null) {
            return ResultUtils.error(ResultEnum.NOT_LOGIN.getCode(), ResultEnum.NOT_LOGIN.getMsg());
        }
        comments.setUserId(loginUser.getUid());

        if (Tools.isNull(vid)) {
            return ResultUtils.error(404, "请输入视频id");
        }
        String author = userService.queryNickNameByUid(videoService.queryUserIdById(vid));
        String desc = videoService.queryDescByVid(vid);
        String title;
        String alert;
        String atNickName = null;
        String uid = videoService.queryUserIdById(vid);
        comments.setVideoId(vid);
        if (Tools.isNull(content)) {
            return ResultUtils.error(ResultEnum.PARAM_ERROR.getCode(), "请输入评论内容!");
        }
        comments.setContent(content.trim());
        if (Tools.isNull(at_uid)) {
            comments.setAtType(2);
            commentPageVo.setAtType(2);
        } else {
            // at_type 为@了人
            comments.setAtType(1);
            comments.setAtUserId(at_uid);
            commentPageVo.setAtType(1);
            CommentPageVo.AtContent atContent = new CommentPageVo.AtContent();
            atContent.setAtUid(at_uid);
            atNickName = userService.queryNickNameByUid(at_uid);
            atContent.setAtNickName(atNickName);
            commentPageVo.setAtContent(atContent);
            // @推送(推送类型，被推送对象id，推送对象id)
            if (at_uid.equals(uid)){
                log.info("推送失败, at对象和作者为同一人, 不用推送此条");
            }else {
                title = loginUser.getNickname() + "评论了" + author + "的\"" + desc + "\"作品";
                alert = "@你 " + content;
                boolean push_result = msgService.pushMsg(4, at_uid, title, alert, null);
                if (push_result) {
                    Msg msg = new Msg();
                    msg.setUserId(at_uid);
                    msg.setCreateTime(new Date());
                    msg.setMsgTitle(title);
                    msg.setMsgContent(alert);
                    msg.setMsgType(3);
                    msgService.save(msg);
                }
            }
        }
        comments.setCreateTime(new Date());
        comments.setLikeCounts(0);
        comments.setAuthorId(videoService.queryUserIdById(vid));
        commentsService.save(comments);
        commentPageVo.setId(comments.getId());
        commentPageVo.setCommentUid(loginUser.getUid());
        commentPageVo.setNickName(userService.queryNickNameByUid(loginUser.getUid()));
        commentPageVo.setAvatar(userService.queryAvatarByUid(loginUser.getUid()));
        commentPageVo.setContent(content);
        commentPageVo.setLikeStatus(false);
        commentPageVo.setCommentTime(comments.getCreateTime());
        commentPageVo.setReplyState(false);
        map.put("comment", commentPageVo);
//        map.put("user", loginUser);
        // 更新视频评论数
        Video video = new Video();
        video.setId(vid);
        int count = commentsService.countByVid(vid);
        video.setCommentCounts(count);
        videoService.updateById(video);
        // 评论推送(推送类型，被推送对象id，推送对象id)

        title = loginUser.getNickname() + "评论了你的\"" + desc + "\"作品";
        if (atNickName == null){
            alert = content;
        }else {
            alert = "@" + atNickName + " " + content;
        }
        JsonObject json = new JsonObject();
        json.addProperty("commentCount", count);
        json.addProperty("videoId", vid);
        boolean push_result = msgService.pushMsg(3, uid, title, alert, json);
        if (push_result) {
            Msg msg = new Msg();
            msg.setUserId(uid);
            msg.setCreateTime(new Date());
            msg.setMsgTitle(title);
            msg.setMsgContent(alert);
            msg.setMsgType(3);
            msgService.save(msg);
        }
        return ResultUtils.success("已成功评论本条内容!", map);
    }


    @ApiOperation(value = "回复评论", notes = "作者回复评论")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "cid", value = "评论id, 回复哪条评论", required = true),
            @ApiImplicitParam(paramType = "query", name = "reply_content", value = "回复内容", required = true)})
    @PostMapping("/reply")
    public JsonResult replyComment(
            @RequestParam(value = "cid") String cid,
            @RequestParam(value = "reply_content") String reply_content
    ) {
        map.clear();
        map.put("path", "/api/comment/reply");
        // 更新评论表
        LoginUser loginUser = (LoginUser) getUser4Session();
        Comments comments = new Comments();
        if (loginUser == null) {
            return ResultUtils.error(ResultEnum.NOT_LOGIN.getCode(), ResultEnum.NOT_LOGIN.getMsg());
        }
        if (Tools.isNull(cid)) {
            return ResultUtils.error(404, "请输入所要回复的评论id");
        }
        comments.setId(Integer.valueOf(cid));
        if (Tools.isNull(reply_content)) {
            return ResultUtils.error(ResultEnum.PARAM_ERROR.getCode(), "请输入回复内容!");
        }
        // TODO 判断是否已经回复过，查询回复内容是否为空 ==> 不允许多次回复
        comments.setReplyContent(reply_content.trim());
        comments.setReplyTime(new Date());
        commentsService.updateById(comments);
        comments = commentsService.getById(Integer.valueOf(cid));
        CommentPageVo commentPageVo = new CommentPageVo();
        commentPageVo.setId(comments.getId());
        commentPageVo.setCommentUid(comments.getUserId());
        commentPageVo.setContent(comments.getContent());
        commentPageVo.setCommentTime(comments.getCreateTime());
        if (zanService.queryIdByUserIdAndZanObjId(loginUser.getUid(), cid) != null) {
            commentPageVo.setLikeStatus(true);
        }
        commentPageVo.setAtType(comments.getAtType());
        if (comments.getAtType() == 1) {
            CommentPageVo.AtContent atContent = new CommentPageVo.AtContent();
            atContent.setAtUid(comments.getAtUserId());
            atContent.setAtNickName(userService.queryNickNameByUid(comments.getAtUserId()));
            commentPageVo.setAtContent(atContent);
        }
        commentPageVo.setContent(comments.getContent());
        commentPageVo.setNickName(userService.queryNickNameByUid(comments.getUserId()));
        commentPageVo.setAvatar(userService.queryAvatarByUid(comments.getUserId()));
        CommentPageVo.AuthorReply authorReply = new CommentPageVo.AuthorReply();
        authorReply.setReplyContent(reply_content.trim());
        authorReply.setAuthorNickName(userService.queryNickNameByUid(loginUser.getUid()));
        authorReply.setAuthorAvatar(userService.queryAvatarByUid(loginUser.getUid()));
        authorReply.setReplyTime(new Date());
        log.info("comment==>{}", comments);

        commentPageVo.setCommentTime(comments.getCreateTime());
        commentPageVo.setReplyState(true);
        commentPageVo.setAuthorReply(authorReply);
        map.put("comment", commentPageVo);
//        map.put("user", loginUser);
        return ResultUtils.success("已成功回复!", map);
    }

    @ApiOperation(value = "评论点赞", notes = "评论点赞和取消点赞")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "cid", value = "评论id", required = true)})
    @PostMapping("/zan")
    public JsonResult zan(
            @RequestParam(value = "cid") String cid
    ) {
        map.clear();
        map.put("path", "/api/comment/zan");
        LoginUser user = (LoginUser) getUser4Session();
        log.info("zanComment: loginUser ==> {}", user);
        if (user == null) {
            return ResultUtils.error(ResultEnum.NOT_LOGIN.getCode(), ResultEnum.NOT_LOGIN.getMsg());
        }
        // 先查询当前评论有多少个赞
//        Integer count = commentsService.queryLikeCountsById(Integer.valueOf(cid));
        Comments comments = new Comments();
        comments.setId(Integer.valueOf(cid));
        // zanType => 2 评论赞
        if (zanService.zanOrCancelZan(2, user.getUid(), cid)) {
            Integer count = zanService.countByZanObjId(cid);
            comments.setLikeCounts(count);
            map.put("likeCounts", count);
            map.put("likeStatus", true);
            // update
            commentsService.updateById(comments);
            log.info("zan success ==> {}", map);
            return ResultUtils.success("已点赞", map);
        }
        Integer count = zanService.countByZanObjId(cid);
        comments.setLikeCounts(count);
        commentsService.updateById(comments);
        map.put("likeCounts", count);
        map.put("likeStatus", false);
        log.info("cancel zan success ==> {}", map);
        return ResultUtils.success("已取消点赞", map);
    }
}
